//

#import "MB_SqlView.h"

@implementation MB_SqlView

- (instancetype)initWithData:(NSString *)entityName dataName:(NSString *)dataName success:(void(^)(void))success fail:(void(^)(NSError *__nullable error))fail
{
    if (self = [super init]) {
        
        _entityName = entityName;
        _dataName = dataName;
        // 初始化上下文
        self.msContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        if (dataName) {
            //获取模型路径
            NSURL *modelURL = [[NSBundle mainBundle] URLForResource:dataName withExtension:@"momd"];
            //根据模型文件创建模型对象
            self.objModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        } else { // 从应用程序包中加载模型文件
            self.objModel = [NSManagedObjectModel mergedModelFromBundles:nil];
        }
        
        // 以传入模型方式初始化持久化存储库
        self.persistent = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_objModel];
        
        // 添加一个持久化存储库并设置类型和路径，NSSQLiteStoreType：SQLite作为存储库
        NSError *error = nil;
        NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSString *sqlPath = [docStr stringByAppendingPathComponent:@"MB.sqlite"];
        //版本前一
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,                             nil];
        [self.persistent addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlPath] options:options error:&error];
        if (error) {
            if (fail) {
                fail(error);
            }
        } else {
            // 设置上下文所要关联的持久化存储库
            self.msContext.persistentStoreCoordinator = self.persistent;
            if (success) {
                success();
            }
        }
    }
    
    return self;
}

// 添加数据
- (void)mb_insertNewEntity:(NSDictionary *)dict success:(void(^)(void))success fail:(void(^)(NSError * __nullable error))fail
{
    if (!dict||dict.allKeys.count == 0) return;
    // 实体对象存储属性值（相当于数据库中将一个值存入对应字段)
    
    NSManagedObject *newEntity = [NSEntityDescription insertNewObjectForEntityForName:self.entityName inManagedObjectContext:self.msContext];
    for (NSString *key in [dict allKeys]) {
        [newEntity setValue:[dict objectForKey:key] forKey:key];
    }
    
    // 保存信息，同步数据
    NSError *error = nil;
    BOOL result = [self.msContext save:&error];
    if (!result) {
        if (fail) {
            fail(error);
        }
    } else {
        if (success) {
            success();
        }
    }
}

// 查询数据
- (void)mb_readEntity:(NSArray * __nullable)sequenceKeys ascending:(BOOL)isAscending filterStr:(NSString * __nullable)filterStr success:(void(^)(NSArray *results))success fail:(void(^)(NSError *__nullable error))fail
{
    // 1.初始化一个查询请求
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    // 2.设置要查询的实体
    NSEntityDescription *desc = [NSEntityDescription entityForName:self.entityName inManagedObjectContext:self.msContext];
    request.entity = desc;
    // 3.设置查询结果排序
    if (sequenceKeys&&sequenceKeys.count>0) { // 如果进行了设置排序
        NSMutableArray *array = [NSMutableArray array];
        for (NSString *key in sequenceKeys) {
            /**
             *  设置查询结果排序
             *  isAscending:是否升序
             */
            NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:key ascending:isAscending];
            [array addObject:sort];
        }
        if (array.count>0) {
            request.sortDescriptors = array;// 可以添加多个排序描述器，然后按顺序放进数组即可
        }
    }
    // 4.设置条件过滤
    if (filterStr) { // 如果设置了过滤语句
        NSPredicate *predicate = [NSPredicate predicateWithFormat:filterStr];
        request.predicate = predicate;
    }
    // 5.执行请求
    NSError *error = nil;
    NSArray *objs = [self.msContext executeFetchRequest:request error:&error]; // 获得查询数据数据集合
    if (error) {
        if (fail) {
            fail(error);
        }
    } else{
        if (success) {
            success(objs);
        }
    }
}


//删除
- (void)mb_deleteEntity:(NSManagedObject *)model key:(id )key success:(void (^)(void))success fail:(void (^)(NSError * _Nullable))fail  {
    
    //创建删除请求
    NSFetchRequest *deleRequest = [NSFetchRequest fetchRequestWithEntityName:_entityName];
    
    //删除条件
    NSPredicate *pre = [NSPredicate predicateWithFormat:key];
    deleRequest.predicate = pre;
    
    NSError *error = nil;
    //返回需要删除的对象数组
    NSArray *deleArray =  [_msContext executeFetchRequest:deleRequest error:&error];
    
    // 错误处理
    if (error) {
        NSLog(@"Department Search Error : %@", error);
    }
    
    //从数据库中删除//循环删除
    for (NSManagedObject *model in deleArray) {
        [_msContext deleteObject:model];
    }
    // 同步到数据库
    [self.msContext save:&error];
    if (error) {
        if (fail) {
            fail(error);
        }
    } else {
        if (success) {
            success();
        }
    }
}


// 更新数据
- (void)mb_updateEntity:(NSDictionary *)dict key:(id)key success:(void (^)(void))success fail:(void (^)(NSError * _Nullable))fail
{
    //修改数据
    NSFetchRequest *request = [[NSFetchRequest alloc] init];//创建请求
    
    request.entity = [NSEntityDescription entityForName:_entityName inManagedObjectContext:_msContext];//找到我们的Person
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:key];//查询条件：name等于小明
    request.predicate = predicate;
    
    NSError *error = nil;
    NSArray *objs = [_msContext executeFetchRequest:request error:&error];//执行请求
    if (error) {
        [NSException raise:@"查询错误" format:@"%@", [error localizedDescription]];
    }
    // 遍历数据
    for (NSManagedObject *obj in objs) {
        for (NSString *key in [dict allKeys]) {
            if (![[dict objectForKey:key] isEqual:@""]) {
                [obj setValue:[dict objectForKey:key] forKey:key];
            }
        }
    }
    //
    [self.msContext save:&error];
    if (error) {
        if (fail) {
            fail(error);
        }
    } else {
        if (success) {
            success();
        }
    }
    
}


@end
